# -*- coding: utf-8 -*-
# 如果你的程序（包括注释）中包含中文，请加上上面这一行，用于指明编码（utf-8）。
# #号开头的行都是注释。

# 如何编辑本程序：
#     用任何文本编辑器均可编辑。

# 如何运行本程序：
#     在终端中，运行：python pA01_pandas.py
#
# 依赖模块：
#     pandas  (pip install pandas)
#

# pandas is designed for working with tabular or heterogeneous data. 
# NumPy, by contrast, is best suited for working with homogeneous numerical array data.

import pandas as pd
import numpy as np

# Two important data structures in pandas: Series and DataFrame


###############################################################
# Series

obj = pd.Series([4, 7, -5, 3])  # 每个序列包含一组值和索引。
print(obj)
print(obj.values)
print(obj.index)  # 默认的索引是0、1、2、...

# 可以指定索引：
obj2 = pd.Series([4, 7, -5, 3], index=['a', 'b', 'c', 'd'])
print(obj2)

# 可以用两种方式索引：
print(obj2[0])
print(obj2['a'])  # 都是该序列中的第一个元素。
print(obj2[[1,3]]
print(obj2[['b', 'd']]  # 打印第2、4个元素（注意两个方括号）

# 筛选和计算：
obj2[obj2 > 0]
obj2 * 2
np.exp(obj2)

# 可以把Series当作python dict对待：index --> value
'b' in obj2
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)  # sorted keys become the index
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)  # 按指定顺序排列

# 判断缺失值
pd.isnull(obj4)
pd.notnull(obj4)

# 根据索引自动对齐：
obj3 + obj4

# 修改索引值：
obj4.index = ['CA', 'OH', 'OR', 'TX']


###############################################################
# DataFrame：由行和列组成的表状结构，每行和每列都有索引。不同列可以具有不同的数据类型。

# 用dict构造DataFrame:

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002, 2003],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)  # 列的顺序按照 'state', 'year', 'pop'的字母顺序排列
# frame = pd.DataFrame(data, columns=['year', 'state', 'pop'])  # 列的顺序按照指定的顺序
# 注意上述三个列表的长度是一样的。

# 用numpy数组构造DataFrame：

frame2 = pd.DataFrame(np.arange(16).reshape((4,4)),	# 4x4的二维数组（矩阵）
	index=['Ohio', 'Colorado', 'Utah', 'New York'],	# index参数指定行名
	columns=['one', 'two', 'three', 'four'])		# columns参数指定列名

# 从文件中读入：

frame3 = pd.read_csv('data/students.csv')
frame3 = pd.read_csv('data/students.tab', sep='\t')	# tab间隔
frame3 = pd.read_csv('data/students.tab', sep='\s+')	# 一个或多个空白间隔
frame4 = pd.read_csv('data/students.csv', index_col='Name')	#将其中一列指定为行名


# 打印前5行：
print(frame.head())

# 取出其中的一个Series：
frame.state  # 用这种方式，列名必须是符合变量命名方式的。
frame['state']  # 用这种方式，任何形式的列名都可以。

# 在DataFrame中增加一列：
frame2['five'] = [100,200,300,400]

frame.T  # 转置
frame.values  # 返回numpy数组，一般用不到


# 通过行、列选择一个子集：

frame4.loc[['Alice','Bob'], ['Major', 'GPA']]	# 用行名和列名列表指定
frame4.loc[['Alice','Bob'],:]	# 某些行，所有列
frame4.loc[:, ['Major', 'GPA']]	# 所有行，某些列
frame4.iloc[[0,1], [2,3]]	# 用行和列的序号列表指定

# 通过值来选择：

frame2 < 5
frame2[frame2<5] = 0	# 将所有小于5的元素设置为0


# 数学运算

df1 = pd.DataFrame(np.arange(12.0).reshape((3,4)), columns=list('abcd'))
df2 = pd.DataFrame(np.arange(20.0).reshape((4,5)), columns=list('abcde'))
df1 + df2
df1.add(df2, fill_value=0)
1/df1

df1.sum()	# 按列汇总
df1.sum(axis='columns')	# 按行汇总
# 类似的方法还有mean, median, min, max 等。
























